package com.yonyou.pmclouds.plan.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.plan.entity.PlanProgressVO;
import com.yonyou.pmclouds.plan.entity.ProjectScheduleBoardVO;
import com.yonyou.pmclouds.plan.entity.ScheduleItemVO;
import com.yonyou.pmclouds.plan.entity.ScheduleVO;
import com.yonyou.pmclouds.plan.processor.ScheduleOnTimeCompletionRateProcessor;
import com.yonyou.pmclouds.plan.processor.ScheduleSetParentProgressProcessor;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleHandleService;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleProgressCalculateService;
import com.yonyou.pmclouds.plan.utils.ScheduleDateCalculateUtil;
import com.yonyou.pmclouds.plan.utils.ScheduleProgressCalculateUtil;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 根据子级推算父级进度百分比
 * @Author: zhangzhonghao
 * @Date: 2020-03-06
 */
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = IScheduleProgressCalculateService.class)
public class ScheduleProgressCalculateServiceImpl implements IScheduleProgressCalculateService{

    @Autowired
    private IScheduleHandleService handleService;

    @Autowired
    private ScheduleSetParentProgressProcessor setParentProgressProcessor;

    @Override
    public ScheduleVO[] calculate(ScheduleVO[] scheduleVOS, PlanProgressVO[] planProgressVOS) throws BusinessException {
        if(scheduleVOS == null || scheduleVOS.length <= 0){
            return scheduleVOS;
        }
        setNewProgressTOItem(scheduleVOS, planProgressVOS);

        for(ScheduleVO scheduleVO : scheduleVOS){
            handleService.addIteratorAfterProcessor(setParentProgressProcessor);
            handleService.handle(scheduleVO, scheduleVO);
        }

        calculate(scheduleVOS);

        return scheduleVOS;
    }

    @Override
    public ScheduleVO[] calculate(ScheduleVO[] scheduleVOS) throws BusinessException {
        if(scheduleVOS == null || scheduleVOS.length <= 0){
            return null;
        }

        for(ScheduleVO scheduleVO : scheduleVOS){

            computedParentProgress(scheduleVO);

            setStartAndEndDate(scheduleVO);
        }
        return scheduleVOS;
    }

    @Override
    public ProjectScheduleBoardVO[] calculate(ProjectScheduleBoardVO[] scheduleBoardVOS) throws BusinessException {
        if(scheduleBoardVOS == null || scheduleBoardVOS.length <= 0){
            return null;
        }

        for(ProjectScheduleBoardVO scheduleBoardVO : scheduleBoardVOS){

            // 计算项目的计划开始、结束时间
            ScheduleDateCalculateUtil.calculateParentPlanDate(scheduleBoardVO);
            // 计算项目进度
            ScheduleProgressCalculateUtil.computedParentProgress(scheduleBoardVO);

            List<ScheduleVO> scheduleVOList = scheduleBoardVO.getScheduleVOList();
            if(scheduleVOList == null || scheduleVOList.size() <= 0){
                continue;
            }

            int totalFinishCount = 0;
            int onTimeCount = 0;
            for(ScheduleVO scheduleVO : scheduleVOList){
                // 计算项目按时完成率：按时完成的叶子节点个数／完成的叶子节点个数
                ScheduleOnTimeCompletionRateProcessor completionRateProcessor = new ScheduleOnTimeCompletionRateProcessor();
                handleService.addIteratorBeforeProcessor(completionRateProcessor);
                handleService.handle(scheduleVO, scheduleVO);
                totalFinishCount = completionRateProcessor.getTotalFinishCount();
                onTimeCount = completionRateProcessor.getOnTimeCount();
            }



            if (totalFinishCount != 0) {
                scheduleBoardVO.setOnTimeCompletionRate((int) Math.floor((onTimeCount * 100 / totalFinishCount)));
            }

        }

        return scheduleBoardVOS;
    }

    private void setNewProgressTOItem(ScheduleVO[] scheduleVOS, PlanProgressVO[] planProgressVOS){
        if(planProgressVOS == null || planProgressVOS.length <= 0){
            return;
        }

        Map<String, ScheduleItemVO> itemVOMap = new HashMap<>();
        for(ScheduleVO scheduleVO : scheduleVOS){
            ScheduleItemVO[] scheduleItemVOS = scheduleVO.getScheduleItemVOS();
            getItemWithPkMap(scheduleItemVOS, itemVOMap);
        }

        for(PlanProgressVO progressVO : planProgressVOS){
            itemVOMap.get(progressVO.getPkPlan()).setProgressVO(progressVO);
        }
    }

    private void getItemWithPkMap(ScheduleItemVO[] itemVOs, Map<String, ScheduleItemVO> itemVOMap){
        for(ScheduleItemVO itemVO : itemVOs){
            itemVOMap.put(itemVO.getPkScheduleItem(), itemVO);
            if(itemVO.getChildren() != null && itemVO.getChildren().length > 0){
                getItemWithPkMap(itemVO.getChildren(), itemVOMap);
            }
        }
    }

    /**
     * 由子表任务计算计划的实际开始、结束时间
     * @param scheduleVO 计划编制
     */
    private void setStartAndEndDate(ScheduleVO scheduleVO) {
        ScheduleDateCalculateUtil.calculateParentDate(scheduleVO);
    }

    private void computedParentProgress(ScheduleVO scheduleVO) {
        ScheduleProgressCalculateUtil.computedParentProgress(scheduleVO);
    }

}
